package com.chuangke.mds.service;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletResponse;

import com.alibaba.druid.util.StringUtils;
import com.chuangke.admin.data.builder.DeptDataBuilder;
import com.chuangke.admin.data.builder.UserDataBuilder;
import com.chuangke.admin.entity.SysDict;
import com.chuangke.admin.service.SysDictService;
import com.chuangke.common.data.builder.DataBuildConfig;
import com.chuangke.common.data.builder.DataBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.chuangke.flow.entity.FlowHiTask;
import com.chuangke.flow.service.FlowQueryService;
import com.chuangke.mds.dao.TechnologyProcessProcedureDao;
import com.chuangke.mds.dao.mapper.TechnologyProcessProcedureNodeSimulateMapper;
import com.chuangke.mds.entity.Material;
import com.chuangke.mds.entity.Product;
import com.chuangke.mds.entity.TechnologyProcess;
import com.chuangke.mds.entity.TechnologyProcessProcedure;
import com.chuangke.mds.entity.TechnologyProcessProcedureNodeSimulate;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;

/**
 * @author panyingzu
 * @title MdsSimulateReportQuarterService
 * @description
 * @Date 2025/10/2 15:20
 */
@Service
public class MdsSimulateReportQuarterService {
    @Autowired
    private TechnologyProcessProcedureNodeSimulateMapper technologyProcessProcedureNodeSimulateMapper;
    @Autowired
    private TechnologyProcessProcedureDao technologyProcessProcedureDao;
    @Autowired
    private TechnologyProcessService technologyProcessService;
    @Autowired
    private ProductService productService;
    @Autowired
    private MaterialService materialService;
    @Autowired
    private FlowQueryService flowQueryService;
    @Autowired
    private SysDictService sysDictService;
    public static final String FZCSDETAIL = "fzcsDetail";
    public static final String GYCSDETAIL = "gycsDetail";

    /**
     * 导出仿真报告模板
     * @param id
     * @param response
     * @throws IOException
     */
    public void exportSimulate(String id, HttpServletResponse response) throws IOException {
        TechnologyProcessProcedureNodeSimulate report = technologyProcessProcedureNodeSimulateMapper.selectById(id);
        TechnologyProcessProcedure procedure = technologyProcessProcedureDao.getOne(new QueryWrapper<TechnologyProcessProcedure>().lambda().eq(TechnologyProcessProcedure::getId, report.getProcedureId()));
        TechnologyProcess process = technologyProcessService.load(procedure.getProcessId());
        Map<String, String> productMap =productService.getAll().stream().collect(Collectors.toMap(Product::getId, Product::getName));
        Map<String, String> materialMap = materialService.getList().stream().collect(Collectors.toMap(Material::getId, Material::getName));

        String templateFilePath = getTemplateFilePath(report.getSimulateType());
        //仿真参数
        Map<String, Object> fzMap = organizeDatas(report.getExecuteParam(),FZCSDETAIL);//new ArrayList<>();
        //工艺参数
        Map<String, Object> map = organizeDatas(procedure.getProcedureData(),GYCSDETAIL);
        map.put(FZCSDETAIL,fzMap.get(FZCSDETAIL));
        //基本信息
        map.put("id",report.getId());
        map.put("name",report.getName());
        map.put("nodeName",procedure.getName());

        map.put("processName",process.getName());
        map.put("productName",productMap.get(process.getProductId()));
        map.put("materialName",materialMap.get(process.getMaterialId()));
        map.put("createAt",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(report.getCreatedAt()));
        List<TechnologyProcessProcedureNodeSimulate> reportList=new ArrayList<>();
        reportList.add(report);
        DataBuilder.of(reportList).appendBuilder(new UserDataBuilder(), new DataBuildConfig("createdBy", "createdByName")).build();

        map.put("applicant",reportList.get(0).getCreatedByName());
        Map<String, SysDict> typeMap =sysDictService.findMap("mds_product_mx_type");
        String simulateType = getSimulateTypeName(report.getSimulateType(),typeMap);
        map.put("simulateType",simulateType);
        //获取单据的审批节点及审批人
        map.put("simulateSupervisor",getSimulateSupervisor(report.getId()));

        Configure config = Configure.builder().bind(GYCSDETAIL, new LoopRowTableRenderPolicy())
                .bind(FZCSDETAIL, new LoopRowTableRenderPolicy()).build();

        File templateFile = ResourceUtils.getFile(templateFilePath);
        XWPFTemplate template = XWPFTemplate.compile(templateFile,config).render(map);

        String fileName = String.format("仿真分析报告.docx");
        // 设置强制下载不打开
        response.setContentType("application/force-download");
        response.addHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(fileName, "utf-8"));
        OutputStream out = response.getOutputStream();
        template.write(out);
        out.flush();
        out.close();
        template.close();
    }

    /**
     * 获取仿真类型名称
     * @param simulateType
     * @param typeMap
     * @return
     */
    private String getSimulateTypeName(String simulateType, Map<String, SysDict> typeMap) {
        Map<String,String> result=new HashMap<>();
        typeMap.forEach((key,value)->{
            String extStr01 = value.getExtStr01();
            if(!StringUtils.isEmpty(extStr01)){
                String[] arr=extStr01.split(";");
                for (String item : arr) {
                    String[] itemArr = item.split(":");
                    result.put(itemArr[0], itemArr[1]);
                }
            }
        });
        return result.get(simulateType);
    }

    /**
     * 获取仿真主管
     * @param billId
     * @return
     */
    private String getSimulateSupervisor(String billId){
        String simulateSupervisor="";
        Map<String,Map<String,Object>> flowMap=flowQueryService.listTask(billId);
        if(!flowMap.isEmpty()){
            String nodeId="f26f778d-797e-4520-a1cb-bcbe857695f4";//仿真主管节点ID
            List<Map<String, Object>> nodeList =flowMap.values().stream().filter(row -> row.get("id").equals(nodeId)).collect(Collectors.toList());
            if(!nodeList.isEmpty()){
                List<FlowHiTask> hiTasks = (List<FlowHiTask>) nodeList.get(0).get("taskUsers");
                if(!hiTasks.isEmpty()){
                    simulateSupervisor=hiTasks.get(hiTasks.size()-1).getUserName();
                }
            }
        }
        return simulateSupervisor;
    }
    private Map<String, Object> organizeDatas(String executeParam,String resultKey) {
        Map<String, Object> resultMap=new HashMap<>();
        List<Map<String, Object>> gycsDetail=new ArrayList<>();
        Map<String,Object> param= JSON.parseObject(executeParam);
        JSONArray tableDatas = (JSONArray) param.get("tableData");
        for (int i = 0; i < tableDatas.size(); i++) {
            Map<String,Object> data=new HashMap<>();
            JSONObject tableData = tableDatas.getJSONObject(i);
            tableData.keySet().forEach(key -> {
                data.put(key, tableData.get(key));
            });
            data.put("index", i+1);
            gycsDetail.add(data);
        }

        JSONObject formData = (JSONObject) param.get("formData");
        formData.keySet().forEach(key -> {
            Object value = formData.get(key);
            if (value instanceof JSONArray) {
                //如果是文件的话，单独取出文件名称
                JSONArray array = (JSONArray) value;
                StringBuilder name= new StringBuilder();
                for (Object o : array) {
                    JSONObject jsonObject = (JSONObject) o;
                    name.append(jsonObject.getString("name")).append(";");
                }
                resultMap.put(key, name.toString());
            }else{
                resultMap.put(key, formData.get(key));
            }

        });
        resultMap.put(resultKey, gycsDetail);
        return resultMap;
    }

    private String getTemplateFilePath(String type) {
        if(type.contains("RCL")){
            type="RCL";
        }else if(type.contains("SKJC")){
            type="SKJC";
        }else if (type.contains("GYLX")){
            type="GYLX";
        }
        return "classpath:template/simulate_"+type+".docx";
    }

    /**
     * 导出任务报告模板
     * @param id
     * @param response
     */

    public void exportTechnology(String id, HttpServletResponse response) throws IOException {
        TechnologyProcess process = technologyProcessService.load(id);
        Map<String, String> productMap =productService.getAll().stream().collect(Collectors.toMap(Product::getId, Product::getName));
        Map<String, String> materialMap = materialService.getList().stream().collect(Collectors.toMap(Material::getId, Material::getName));
        String templateFilePath = "classpath:template/task-analyse.docx";
        Map<String, Object> map = new HashMap<>();
        map.put("id",process.getId());
        map.put("name",process.getName());
        map.put("productName",productMap.get(process.getProductId()));
        map.put("materialName",materialMap.get(process.getMaterialId()));
        map.put("createAt",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(process.getCreatedAt()));
        map.put("createByName",process.getCreatedByName());
        map.put("simulateSupervisor",getSimulateSupervisor(id));
        map.put("questionType",process.getQuestionType());
        map.put("questionRemarks",process.getQuestionRemarks());
        map.put("remarks",process.getRemarks());
        File templateFile = ResourceUtils.getFile(templateFilePath);
        XWPFTemplate template = XWPFTemplate.compile(templateFile).render(map);

        String fileName = String.format("任务仿真报告.docx");
        // 设置强制下载不打开
        response.setContentType("application/force-download");
        response.addHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(fileName, "utf-8"));
        OutputStream out = response.getOutputStream();
        template.write(out);
        out.flush();
        out.close();
        template.close();
    }
}
